/*
 * Copyright © 2004-2014 chenYuan. All rights reserved.
 * @Website:wwww.jspx.net
 * @Mail:39793751@qq.com
 * @author: chenYuan , 陈原
 * @License: Jspx.net Framework Code is open source (LGPL)，Jspx.net Framework 使用LGPL 开源授权协议发布。
 * @jvm:jdk1.6+  x86/amd64
 */
package com.jspx.txweb.action;

import com.jspx.boot.environment.Environment;

import com.jspx.boot.sign.LanguageRes;
import com.jspx.json.JSONArray;
import com.jspx.lucene.ChineseAnalyzer;
import com.jspx.json.JSONObject;
import com.jspx.sioc.annotation.Ref;
import com.jspx.txweb.IUserSession;
import com.jspx.txweb.annotation.HttpMethod;
import com.jspx.txweb.annotation.MulRequest;
import com.jspx.txweb.annotation.Operate;
import com.jspx.txweb.annotation.Safety;
import com.jspx.txweb.bundle.Bundle;
import com.jspx.txweb.dao.UploadFileDAO;
import com.jspx.txweb.support.MultipartSupport;
import com.jspx.txweb.table.IUploadFile;
import com.jspx.txweb.util.RequestUtil;
import com.jspx.upload.MultipartRequest;
import com.jspx.upload.UploadedFile;
import com.jspx.util.StringMap;
import com.jspx.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;

/**
 * Created by IntelliJ IDEA.
 * User: chenYuan
 * Date: 12-2-4
 * Time: 下午7:48
 * 上传机制说明, 如果采用flash方式上传，每次只是一个上传文件，
 * 如果使用html type=file 方式上传，为多个文件方式
 * 上传后的图片会自动压缩
 * <p/>
 * 图片 如果大于最大宽度就缩小到最大宽度，这张图作为原图
 * 1.参数thumbnail  成立，生成_s缩图
 * 2.所有图都生成_m手机图片
 * 3.如果已经存在的图片，将已经存在的图片返回，如果已经在的图片，就将现有图片拷贝覆盖到原图片
 */
@HttpMethod(caption = "上传文件")
public class UploadFileAction extends MultipartSupport {
    final private static Logger log = LoggerFactory.getLogger(UploadFileAction.class);
    final static private String[] officeFileTypes = FileSuffixUtil.officeTypes;
    final static private String[] stopExs = new String[]{"php", "jsp", "ftl", "html", "htm", "exe", "com", "bat", "asp", "aspx", "sh", "jar", "js", "dll"};

    private JSONObject json = new JSONObject();
    // 状态
    public static String hashType = "MD5";
    private Object uploadFile = null;
    private boolean useOriginalDate = false;

    public UploadFileAction() {
        setActionResult(NONE);
    }

    //分片上传，返回显示分片状态，满足断点续传，优化速度
    private boolean chunkSate = false;

    public void setChunkSate(boolean chunkSate) {
        this.chunkSate = chunkSate;
    }


    @Safety(request = false)
    public void setUseOriginalDate(boolean useOriginalDate) {
        this.useOriginalDate = useOriginalDate;
    }

    @Safety(request = false)
    public void setHashType(String hashType) {
        UploadFileAction.hashType = hashType;
    }


    /**
     * @return 得到配置允许上传的文件类型
     */
    public String getFileTypes() {
        IUserSession userSession = (IUserSession) getUserSession();
        if (userSession != null) {
            fileTypes = userSession.getRole(uploadFileDAO.getNamespace()).getUploadFileTypes();
        }
        if (StringUtil.isNULL(fileTypes) && config != null)
            fileTypes = config.getString(Environment.allowedTypes);


        if ("*".equalsIgnoreCase(fileTypes)) {
            String[] uploadTypes = new String[0];
            uploadTypes = ArrayUtil.join(uploadTypes, FileSuffixUtil.imageTypes);
            uploadTypes = ArrayUtil.join(uploadTypes, FileSuffixUtil.zipTypes);
            uploadTypes = ArrayUtil.join(uploadTypes, FileSuffixUtil.videoTypes);
            uploadTypes = ArrayUtil.join(uploadTypes, FileSuffixUtil.officeTypes);
            fileTypes = ArrayUtil.toString(uploadTypes, StringUtil.COMMAS);
        }

        fileTypes = StringUtil.replace(fileTypes, StringUtil.COMMAS, StringUtil.SEMICOLON);
        return fileTypes;

    }

    /**
     * @return 最大上传限制
     */
    public int getMaxPostSize() {
        IUserSession userSession = (IUserSession) getUserSession();
        if (userSession != null) {
            maxPostSize = userSession.getRole(uploadFileDAO.getNamespace()).getUploadSize() * 1024;
        }
        if (maxPostSize < 0 && config != null)
            maxPostSize = config.getInt(Environment.uploadMaxSize) * 1024;
        return maxPostSize;
    }

    /**
     * @return 得到上传路径
     */
    public String getSaveDirectory() {
        return getUploadDirectory(config);
    }

    /**
     * @return 得到安装路径
     * @throws Exception
     */
    private String getSetupPath() throws Exception {
        String setupPath = FileUtil.mendPath(config.getString(Environment.setupPath));
        if (!FileUtil.isDirectory(setupPath)) {
            setupPath = FileUtil.mendPath(FileUtil.getParentPath(getTemplatePath()));
            config.save(Environment.setupPath, setupPath);
            addFieldInfo(Environment.warningInfo, language.getLang(LanguageRes.setupConfigPathError) + ":" + setupPath);
        }
        return setupPath;
    }

    /**
     * @param config 配置接口
     * @return 上传路径的计算方式配置方式
     */
    @Safety(request = false)
    public static String getUploadDirectory(Bundle config) {
        String saveDirectory = FileUtil.mendPath(config.getString(Environment.uploadPath));
        if (!FileUtil.isDirectory(saveDirectory))
            saveDirectory = FileUtil.mendPath(config.getString(Environment.setupPath)) + FileUtil.mendPath(config.getString(Environment.uploadPath));
        boolean uploadPathType = config.getBoolean(Environment.uploadPathType);
        if (uploadPathType) {
            saveDirectory = FileUtil.mendPath(saveDirectory) + DateUtil.toString("yyyyMM") + "/";
        } else saveDirectory = FileUtil.mendPath(saveDirectory) + DateUtil.toString("yyyy") + "/";
        return saveDirectory;
    }

    /**
     * @param config 配置
     * @param name   名称
     * @return 得到文件
     */
    @Safety(request = false)
    public static File getUploadFile(Bundle config, String name) {
        String searchPathList = config.getString(Environment.searchPaths);
        String[] searchPaths = StringUtil.split(StringUtil.convertCR(searchPathList), StringUtil.CR);
        searchPaths = ArrayUtil.add(searchPaths, config.getString(Environment.setupPath));
        searchPaths = ArrayUtil.add(searchPaths, config.getString(Environment.setupPath) + "/" + config.getString(Environment.uploadPath));
        searchPaths = ArrayUtil.add(searchPaths, (new File(config.getString(Environment.setupPath))).getParent());
        return FileUtil.getFile(searchPaths, name);
    }

    /**
     * @return 是否覆盖
     */
    public boolean getCovering() {
        return config.getBoolean(Environment.uploadCovering);
    }

    /**
     * @param multipartRequest 请求接口
     */
    @Safety(request = false)
    @MulRequest(covering = "@covering", saveDirectory = "@saveDirectory", fileTypes = "@fileTypes", maxPostSize = "@maxPostSize")
    public void setMultipartRequest(MultipartRequest multipartRequest) {
        request = this.multipartRequest = multipartRequest;
    }

    /**
     * DAO 对象
     */
    private UploadFileDAO uploadFileDAO;
    @Safety(request = false)
    public void setUploadFileDAO(UploadFileDAO uploadFileDAO) {
        this.uploadFileDAO = uploadFileDAO;
    }

    /**
     * 中文分词
     */
    private ChineseAnalyzer chineseAnalyzer;

    @Safety(request = false)
    @Ref(name = Environment.chineseAnalyzer)
    public void setChineseAnalyzer(ChineseAnalyzer chineseAnalyzer) {
        this.chineseAnalyzer = chineseAnalyzer;
    }

    private String hash = StringUtil.empty;

    public void setHash(String hash) {
        this.hash = hash;
    }

    @Operate(caption = "hash验证")
    public void hasHash() throws Exception {
        json.put("OK", 0);
        json.put("success", false);
        if (isGuest()) {
            json.put(Environment.message, language.getLang(LanguageRes.needLogin));
            setResult(json);
            return;
        }

        if (StringUtil.isNULL(hash)) {
            json.put(Environment.message, language.getLang(LanguageRes.invalidParameter));
            setResult(json);
            return;
        }

        Object alreadyUploadFile = uploadFileDAO.getForHash(hash);
        IUploadFile checkUploadFile = (IUploadFile) alreadyUploadFile;
        if (checkUploadFile != null && hash.equalsIgnoreCase(checkUploadFile.getHash())) {
            json.put(Environment.message, language.getLang(LanguageRes.alreadyExist));
            json.put("success", true);
            json.put("hash", hash);
            json.put("hashType", hashType);
            json.put("OK", 1);
            setResult(json);
            return;
        }
        setResult(json);
    }

    @Operate(caption = "秒传")
    public void fastUpload() throws Exception {
        json.put("OK", 0);
        json.put("success", false);
        if (isGuest()) {
            json.put(Environment.message, language.getLang(LanguageRes.needLogin));
            setResult(json);
            return;
        }

        if (StringUtil.isNULL(hash)) {
            json.put(Environment.message, language.getLang(LanguageRes.invalidParameter));
            setResult(json);
            return;
        }

        Object alreadyUploadFile = uploadFileDAO.getForHash(hash);
        IUploadFile checkUploadFile = (IUploadFile) alreadyUploadFile;
        if (checkUploadFile != null && !StringUtil.isNULL(hash) && checkUploadFile.getHash().equals(hash)) {
            File file = getUploadFile(config, checkUploadFile.getFileName());
            if (file == null || !file.exists()) {
                json.put(Environment.message, language.getLang(LanguageRes.fileNotFind));
                setResult(json);
                return;
            }
            IUserSession userSession = (IUserSession) getUserSession();
            if (checkUploadFile.getPutUid() != userSession.getUid()) {
                //不同用户发布的，转存一份
                checkUploadFile.setId(0);
                checkUploadFile.setPutName(userSession.getName());
                checkUploadFile.setPutUid(userSession.getUid());
                checkUploadFile.setIp(getRemoteAddr());
                checkUploadFile.setDownTimes(0);
                uploadFileDAO.save(alreadyUploadFile);
                //验证一遍文件,如果后发布的文件和先发布的不同，用后发布的文件覆盖一次先发布的文件

            } else {
                checkUploadFile.setLastDate(new Date());
                checkUploadFile.setSortDate(new Date());
                uploadFileDAO.update(alreadyUploadFile, new String[]{"lastDate", "sortDate"});
            }

            //已经上传过的文件，在这里就直接返回上次的上传数据
            json.put("fileName", checkUploadFile.getFileName());
            json.put("name", FileUtil.getNamePart(checkUploadFile.getTitle()));

            if (checkUploadFile.getFileName() != null && checkUploadFile.getFileName().startsWith('/' + uploadFileDAO.getNamespace() + '/'))
                json.put("url", checkUploadFile.getFileName());
            else
                json.put("url", '/' + uploadFileDAO.getNamespace() + '/' + checkUploadFile.getFileName());
            json.put("title", checkUploadFile.getTitle());
            json.put("original", checkUploadFile.getTitle());
            json.put("dir", FileUtil.mendPath(FileUtil.getDecrease(getSetupPath(), file.getParent())));
            json.put("id", checkUploadFile.getId());
            json.put("size", checkUploadFile.getFileSize());
            json.put("type", checkUploadFile.getFileType());
            json.put("hash", checkUploadFile.getHash());
            json.put("error", 0);
            json.put("fileType", checkUploadFile.getFileType());
            json.put("success", true);
            json.put("state", "SUCCESS");
            json.put("successed", true);
            json.put(Environment.message, language.getLang(LanguageRes.success));
            //兼容 plupload  begin
            json.put("OK", 1);
            uploadFileDAO.evict(uploadFileDAO.getClassType());
            //兼容 plupload  end
            setResult(json);
        }
    }

    private String fileName = StringUtil.empty;

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    @Operate(caption = "续传判断")
    public void lastChunk() throws Exception {
        json.put("OK", 0);
        json.put("success", false);
        if (isGuest()) {
            json.put(Environment.message, language.getLang(LanguageRes.needLogin));
            setResult(json);
            return;
        }
        IUserSession userSession = (IUserSession) getUserSession();
        UploadedFile uf = new UploadedFile(fileName, getUploadDirectory(config), fileName, fileName, "application/octet-stream", FileUtil.getTypePart(fileName));
        int diskChunk = uf.getLastChunk(NumberUtil.toString(userSession.getUid()));
        json.put("lastChunk", diskChunk);
        json.put("chunks", uf.getChunks());
        //兼容 plupload  begin
        if (diskChunk > 1) {
            json.put("OK", 1);
            json.put("success", true);
        }
        json.put(Environment.message, "chunk upload " + language.getLang(LanguageRes.success));
        //兼容 plupload  end
        setResult(json);
    }

    /**
     * 兼容swfupload 和 kindeditor, 和UEditor 1.2.0 的返回结果，当然普通页面上传也没问题
     *
     * @return json 返回结果
     * @throws Exception
     */
    @Operate(caption = "上传")
    public String execute() throws Exception {
        if (getResult() != null) return ROC;
        //--------------------------------------------------------------------------------------------------------------
        if (uploadFileDAO == null) {
            json.put("repair", false);
            json.put("success", false);
            json.put("error", 1);
            json.put("state", "error");
            json.put("thumbnail", 0);
            json.put(Environment.message, "not config uploadFileDAO");
            json.put("namespace", getRootNamespace());
            return ROC;
        }
        json.put("repair", false);
        json.put("success", false);
        json.put("error", 1);
        json.put("state", "error");
        json.put("thumbnail", 0);
        json.put("namespace", uploadFileDAO.getNamespace());

        //兼容 plupload  begin
        json.put("OK", 0);
        json.put(Environment.message, language.getLang(LanguageRes.invalidParameter));
        //兼容 plupload  end

        if (multipartRequest == null && !RequestUtil.isMultipart(request)) {
            json.put("fileName", "");
            json.put("url", "");
            json.put("original", "");
            json.put("dir", "");
            json.put("name", "");
            json.put("thumbnail", 0);

            //兼容 plupload  begin
            json.put("OK", 0);
            //兼容 plupload  end

            json.put(Environment.message, language.getLang(LanguageRes.uploadRequestError));
            setResult(json);
            return ROC;
        }

        if (isGuest()) {
            json.put("fileName", "");
            json.put("url", "");
            json.put("original", "");
            json.put("dir", "");
            json.put("name", "");
            json.put("thumbnail", 0);

            //兼容 plupload  begin
            json.put("OK", 0);
            json.put(Environment.message, language.getLang(LanguageRes.needLogin));
            //兼容 plupload  end

            for (UploadedFile uf : multipartRequest.getFiles()) {
                FileUtil.delete(uf.getFile());
            }
            setResult(json);
            return ROC;
        }

        IUserSession userSession = (IUserSession) getUserSession();
        boolean useUploadConverter = config.getBoolean(Environment.useUploadConverterTxt);
        String setupPath = getSetupPath();
        boolean thumbnail = getBoolean("thumbnail");
        int maxImageWidth = config.getInt(Environment.maxImageWidth, 1280);
        JSONArray fileJson = new JSONArray();
        for (UploadedFile uf : multipartRequest.getFiles()) {
            if (ArrayUtil.inArray(stopExs, uf.getFileType(), true)) {
                json.put("fileName", StringUtil.empty);
                json.put("url", StringUtil.empty);
                json.put("original", StringUtil.empty);

                json.put("title", uf.getOriginal());
                json.put("size", uf.getLength());
                json.put("type", uf.getFileType());

                json.put("dir", StringUtil.empty);
                json.put("name", StringUtil.empty);
                //兼容 plupload  begin
                json.put("OK", 0);
                //兼容 plupload  end
                json.put(Environment.message, language.getLang(LanguageRes.notAllowedFileType) + ":" + uf.getFileType());
                FileUtil.delete(uf.getFile());
                continue;
            }
            if (!uf.isUpload()) {
                json.put("fileName", uf.getFileName());
                json.put("title", uf.getOriginal());
                json.put("size", uf.getLength());
                json.put("type", uf.getFileType());
                json.put("original", uf.getOriginal());
                json.put("url", StringUtil.empty);
                json.put("dir", StringUtil.empty);
                json.put("name", StringUtil.empty);

                //兼容 plupload  begin
                json.put("OK", 0);
                //兼容 plupload  end
                json.put(Environment.message, language.getLang(LanguageRes.notAllowedFileTypeOrUploadError));
                FileUtil.delete(uf.getFile());
                continue;
            }


            //分片上传 begin
            if (uf.isChunkUpload()) {
                json.put("uploadType", "chunk");
                if (uf.moveToChunkFolder(NumberUtil.toString(userSession.getUid()))) {
                    //如果是分片上传,追加进去后直接返回
                    json.put("fileName", uf.getFileName());
                    json.put("url", "");
                    json.put("name", FileUtil.getNamePart(uf.getOriginal()));
                    json.put("original", uf.getOriginal());
                    json.put("title", uf.getOriginal());
                    json.put("size", uf.getLength());
                    json.put("type", uf.getFileType());
                    json.put("dir", "");

                    //添加入最大的分片，判断是否断点续传

                    if (uf.isFolderChunkFull(NumberUtil.toString(userSession.getUid()))) {
                        //已经上传完毕
                        if (uf.mergeChunks(NumberUtil.toString(userSession.getUid()))) {
                            json.put("state", "SUCCESS");
                            json.put("successed", true);
                            //兼容 plupload  begin
                            json.put("OK", 1);
                            json.put(Environment.message, language.getLang(LanguageRes.success));
                            //兼容 plupload  end
                        } else {
                            json.put("OK", 0);
                            json.put(Environment.message, language.getLang(LanguageRes.saveFailure));
                            continue;
                        }
                    } else {
                        if (chunkSate) {
                            int diskChunk = uf.getLastChunk(NumberUtil.toString(userSession.getUid()));
                            if (diskChunk > 0 && diskChunk > uf.getChunk()) {
                                json.put("lastChunk", diskChunk);
                                json.put("chunk", uf.getChunk());
                                json.put("chunkSize", uf.getLength());
                                json.put("offset", diskChunk * uf.getLength());
                            }
                        }
                        //兼容 plupload  begin
                        json.put("OK", 1);
                        json.put(Environment.message, "chunk upload " + language.getLang(LanguageRes.success));
                        //兼容 plupload  end
                        continue;
                    }

                } else {
                    json.put("OK", 0);
                    json.put(Environment.message, language.getLang(LanguageRes.saveFailure));
                    continue;
                }
            }
            //分片上传 end

            json.put("uploadType", "file");
            if (uf.moveToTypeDir()) {
                uploadFile = uploadFileDAO.getClassType().newInstance();
                IUploadFile upFile = (IUploadFile) uploadFile;
                upFile.setTitle(FileUtil.getNamePart(uf.getOriginal()));
                if ("Filedata".equalsIgnoreCase(upFile.getTitle()) || "blob".equalsIgnoreCase(upFile.getTitle())) {
                    upFile.setTitle(FileUtil.getNamePart(uf.getFileName()));
                }
                upFile.setFileName(FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + uf.getFileName());
                upFile.setFileSize(uf.getFile().length());
                upFile.setFileType(uf.getFileType());

                if (useUploadConverter && ArrayUtil.inArray(officeFileTypes, uf.getFileType(), true)) {
                    //文档转换,为了方便安卓下编译
                    try {
                        Object readOfficeFile = ClassUtil.newInstance("com.jspx.document.io.AutoReadOfficeFile");
                        BeanUtil.setSimpleProperty(readOfficeFile, "file", uf.getFile());
                        String content = (String) BeanUtil.getProperty(readOfficeFile, "content");
                        content = StringUtil.cut(content, 5000, StringUtil.empty);
                        upFile.setContent(content);
                        upFile.setTags(chineseAnalyzer.getTag(content, StringUtil.space, 6, true));
                    } catch (Exception e) {
                        upFile.setContent(uf.getOriginal());
                        upFile.setTags(chineseAnalyzer.getTag(uf.getOriginal(), StringUtil.space, 3, true));
                    }
                } else {
                    upFile.setContent(FileUtil.getNamePart(uf.getOriginal()));
                    upFile.setTags(chineseAnalyzer.getTag(uf.getOriginal(), StringUtil.space, 3, true));
                }

                upFile.setPutName(userSession.getName());
                upFile.setPutUid(userSession.getUid());
                upFile.setIp(getRemoteAddr());
                upFile.setHash(FileUtil.getHash(uf.getFile(), hashType));
                json.put("hash", upFile.getHash());
                Object alreadyUploadFile = null;
                if (!StringUtil.isNULL(upFile.getHash()))
                    alreadyUploadFile = uploadFileDAO.getForHash(upFile.getHash());
                IUploadFile checkUploadFile = (IUploadFile) alreadyUploadFile;
                if (checkUploadFile != null && !StringUtil.isNULL(upFile.getHash()) && checkUploadFile.getHash().equals(upFile.getHash())) {
                    //当前上传的文件
                    File file = getUploadFile(config, upFile.getFileName());
                    //以前的文件
                    File checkFile = getUploadFile(config, checkUploadFile.getFileName());
                    //如果两个文件大小不同
                    if (checkFile == null&&file!=null&&FileUtil.isFileExist(file.getAbsolutePath())) {
                        checkFile = file;
                        checkUploadFile.setFileName(FileUtil.mendPath(FileUtil.getDecrease(setupPath, getUploadDirectory(config))) + file.getName());
                        uploadFileDAO.update(alreadyUploadFile, new String[]{"fileName"});
                    }

                    if (checkFile!=null&&file!=null&&(!checkFile.exists() || file.length() != checkFile.length())) {
                        if (FileUtil.copy(file, checkFile, true)) {
                            if (!file.equals(checkFile)) {
                                FileUtil.delete(file);
                                file = checkFile;
                            }
                        }
                    }

                    if (checkUploadFile.getPutUid() != userSession.getUid()) {
                        //不同用户发布的，转存一份
                        checkUploadFile.setId(0);
                        checkUploadFile.setPutName(userSession.getName());
                        checkUploadFile.setPutUid(userSession.getUid());
                        checkUploadFile.setIp(getRemoteAddr());
                        checkUploadFile.setDownTimes(0);
                        uploadFileDAO.save(alreadyUploadFile);
                        //验证一遍文件,如果后发布的文件和先发布的不同，用后发布的文件覆盖一次先发布的文件
                    } else {
                        checkUploadFile.setLastDate(new Date());
                        checkUploadFile.setSortDate(new Date());
                        uploadFileDAO.update(alreadyUploadFile, new String[]{"lastDate", "sortDate"});
                    }


                    //判断缩图是否存在 begin
                    if (file!=null)
                    {
                        String thumbnailImg = FileUtil.getThumbnailFileName(file.getName());
                        File thumbnailFile = new File(file.getParentFile(), thumbnailImg);
                        if (thumbnailFile.isFile()) {
                            json.put("thumbnail", 1);
                            String thumbnailPath = FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + thumbnailImg;
                            if (thumbnailPath.startsWith('/' + uploadFileDAO.getNamespace() + '/'))
                                json.put("thumbnailUrl", thumbnailPath);
                            else
                                json.put("thumbnailUrl", '/' + uploadFileDAO.getNamespace() + '/' + thumbnailPath);
                        }
                        //判断缩图是否存在 end
                    }

                    //已经上传过的文件，在这里就直接返回上次的上传数据
                    json.put("fileName", checkUploadFile.getFileName());
                    json.put("name", FileUtil.getNamePart(uf.getOriginal()));

                    if (checkUploadFile.getFileName() != null && checkUploadFile.getFileName().startsWith('/' + uploadFileDAO.getNamespace() + '/'))
                        json.put("url", checkUploadFile.getFileName());
                    else
                        json.put("url", '/' + uploadFileDAO.getNamespace() + '/' + checkUploadFile.getFileName());
                    json.put("title", checkUploadFile.getTitle());
                    json.put("original", uf.getOriginal());
                    json.put("dir", FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())));
                    json.put("id", checkUploadFile.getId());
                    json.put("size", uf.getLength());
                    json.put("type", uf.getFileType());
                    json.put("error", 0);
                    json.put("fileType", checkUploadFile.getFileType());
                    json.put(Environment.message, language.getLang(LanguageRes.success));
                    json.put("success", true);
                    json.put("state", "SUCCESS");
                    json.put("successed", true);
                    //兼容 plupload  begin
                    json.put("OK", 1);
                    //兼容 plupload  end

                } else if (uploadFileDAO != null) {
                    //已经上传成功的,还没有的上传上去的就上传上去
                    IUploadFile thumbnailUploadFile = null;
                    IUploadFile mobileUploadFile = null;
                    if (FileSuffixUtil.isImageSuffix(uf.getFileType())) {
                        File file = uf.getFile();

                        //如果是图片就得到宽高
                        BufferedImage image = null;
                        try {
                            image = ImageIO.read(file);
                        } catch (IOException e1) {
                            json.put("state", ERROR);
                            json.put("success", false);
                            //兼容 plupload  begin
                            json.put("OK", 0);
                            json.put(Environment.message, "不能识别的图片格式");
                            setResult(json);
                            log.info("未知不能识别的图片格式:"+ file.getAbsolutePath());
                            return ROC;
                        }
                        int w = image.getWidth();
                        int h = image.getHeight();

                        if (config.getBoolean(Environment.EXIF_SATE)) {
                            StringMap map = ImageUtil.parsePhotoExif(file, ImageUtil.simpleExifTags);
                            upFile.setAttributes(map.toString());
                        } else
                            upFile.setAttributes("width=" + w + "\r\nheight=" + h);

                        if (image.getWidth() > maxImageWidth) {
                            h = (maxImageWidth / w) * h;
                            if (!file.canWrite()) Thread.sleep(200);
                            boolean repair = ImageUtil.thumbnail(image, new FileOutputStream(file), uf.getFileType(), maxImageWidth, h);
                            json.put("repair", repair);
                        }

                        String thumbnailImg = FileUtil.getThumbnailFileName(uf.getFileName());
                        int width = config.getInt("thumbnailWidth", 400);
                        int height = config.getInt("thumbnailHeight", 400);
                        if (thumbnail) {
                            //创建缩图
                            File thumbnailFile = new File(file.getParent(), thumbnailImg);
                            if (ImageUtil.thumbnail(image, new FileOutputStream(thumbnailFile), uf.getFileType(), width, height)) {
                                json.put("fileName", thumbnailImg);
                                json.put("name", FileUtil.getNamePart(thumbnailImg));
                                json.put("thumbnail", 1);
                                String thumbnailPath = FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + thumbnailImg;
                                if (thumbnailPath.startsWith('/' + uploadFileDAO.getNamespace() + '/'))
                                    json.put("thumbnailUrl", thumbnailPath);
                                else
                                    json.put("thumbnailUrl", '/' + uploadFileDAO.getNamespace() + '/' + thumbnailPath);

                                thumbnailUploadFile = (IUploadFile) uploadFileDAO.getClassType().newInstance();
                                thumbnailUploadFile.setHash(FileUtil.getHash(thumbnailFile, hashType));
                                thumbnailUploadFile.setFileSize(thumbnailFile.length());
                            }
                        }

                        //创建手机图片
                        int mobileWidth = config.getInt("mobileWidth", 480);
                        int mobileHeight = config.getInt("mobileHeight", 480);
                        String mobileImg = FileUtil.getMobileFileName(uf.getFileName());
                        File mobileFile = new File(file.getParent(), mobileImg);
                        if (ImageUtil.thumbnail(image, new FileOutputStream(mobileFile), uf.getFileType(), mobileWidth, mobileHeight)) {
                            json.put("name", FileUtil.getNamePart(mobileImg));
                            json.put("mobile", 1);

                            String mobilePath = FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + mobileImg;
                            if (mobilePath.startsWith('/' + uploadFileDAO.getNamespace() + '/'))
                                json.put("mobileUrl", mobilePath);
                            else
                                json.put("mobileUrl", '/' + uploadFileDAO.getNamespace() + '/' + mobilePath);
                            mobileUploadFile = (IUploadFile) uploadFileDAO.getClassType().newInstance();
                            mobileUploadFile.setHash(FileUtil.getHash(mobileFile, hashType));
                            mobileUploadFile.setFileSize(mobileFile.length());
                        }
                    }

                    //导入日期
                    Date createDate = new Date();
                    if (useOriginalDate && uf.getOriginal().startsWith("[") && uf.getOriginal().contains("]")) {
                        String dataStr = StringUtil.substringBetween(uf.getOriginal(), "[", "]");
                        if (!StringUtil.isNULL(dataStr)) {
                            try {
                                createDate = StringUtil.toDate(dataStr);
                            } catch (Exception e) {
                                createDate = new Date();
                            }
                        }
                    }
                    upFile.setCreateDate(createDate);

                    if (uploadFileDAO.save(uploadFile) >= 0) {

                        if (thumbnailUploadFile != null) {
                            String thumbnailHash = thumbnailUploadFile.getHash();
                            long thumbnailSize = thumbnailUploadFile.getFileSize();
                            BeanUtil.copySimpleProperty(thumbnailUploadFile, upFile);
                            thumbnailUploadFile.setHash(thumbnailHash);
                            thumbnailUploadFile.setFileSize(thumbnailSize);
                            thumbnailUploadFile.setId(0);
                            thumbnailUploadFile.setTitle(upFile.getTitle());
                            thumbnailUploadFile.setTags("缩图");
                            thumbnailUploadFile.setPid(upFile.getId());
                            thumbnailUploadFile.setFileName(FileUtil.getThumbnailFileName(thumbnailUploadFile.getFileName()));
                            uploadFileDAO.save(thumbnailUploadFile);
                        }

                        if (mobileUploadFile != null) {
                            String mobileHash = mobileUploadFile.getHash();
                            long mobileSize = mobileUploadFile.getFileSize();
                            BeanUtil.copySimpleProperty(mobileUploadFile, upFile);
                            mobileUploadFile.setHash(mobileHash);
                            mobileUploadFile.setFileSize(mobileSize);
                            mobileUploadFile.setId(0);
                            mobileUploadFile.setTitle(upFile.getTitle());
                            mobileUploadFile.setTags("手机");
                            mobileUploadFile.setPid(upFile.getId());
                            mobileUploadFile.setFileName(FileUtil.getMobileFileName(mobileUploadFile.getFileName()));
                            uploadFileDAO.save(mobileUploadFile);
                        }

                        json.put("fileName", uf.getFileName());
                        json.put("name", FileUtil.getNamePart(uf.getOriginal()));

                        String urlPath = FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + uf.getFileName();
                        if (urlPath.startsWith('/' + uploadFileDAO.getNamespace() + '/'))
                            json.put("url", FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + uf.getFileName());
                        else
                            json.put("url", '/' + uploadFileDAO.getNamespace() + '/' + FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + uf.getFileName());

                        json.put("purl", uf.getFileName());
                        json.put("name", FileUtil.getNamePart(uf.getOriginal()));
                        json.put("original", uf.getOriginal());
                        json.put("title", uf.getOriginal());
                        json.put("size", uf.getLength());
                        json.put("type", uf.getFileType());
                        json.put("dir", FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())));
                        json.put("id", upFile.getId());
                        json.put("error", 0);
                        json.put("fileType", uf.getFileType());
                        json.put("state", SUCCESS);
                        json.put("success", true);
                        //兼容 plupload  begin
                        json.put("OK", 1);
                        //兼容 plupload  end
                        json.put(Environment.message, language.getLang(LanguageRes.success));
                        setActionLogTitle("上传文件," + uf.getOriginal());
                        setActionLogContent(BeanUtil.toXml(upFile));
                        fileJson.put(json.clone());
                    } else {
                        json.put(Environment.message, language.getLang(LanguageRes.databaseSaveError));
                    }
                } else {
                    json.put("fileName", uf.getFileName());
                    json.put("name", FileUtil.getNamePart(uf.getOriginal()));
                    json.put("fileType", uf.getFileType());

                    String urlPath = FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + uf.getFileName();
                    if (urlPath.startsWith('/' + uploadFileDAO.getNamespace()))
                        json.put("url", FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + uf.getFileName());
                    else
                        json.put("url", '/' + uploadFileDAO.getNamespace() + '/' + FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + uf.getFileName());

                    json.put("original", uf.getOriginal());
                    json.put("dir", FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())));
                    json.put("name", FileUtil.getNamePart(uf.getOriginal()));
                    json.put(Environment.message, language.getLang(LanguageRes.folderWriteError));
                }
            } else {
                //没有移动成功的文件
                json.put("fileType", uf.getFileType());
                json.put("fileName", uf.getFileName());
                json.put("name", FileUtil.getNamePart(uf.getOriginal()));
                json.put("title", uf.getOriginal());
                json.put("size", uf.getLength());
                json.put("type", uf.getFileType());

                String urlPaht = FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + uf.getFileName();
                if (urlPaht.startsWith('/' + uploadFileDAO.getNamespace()))
                    json.put("url", FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + uf.getFileName());
                else
                    json.put("url", '/' + uploadFileDAO.getNamespace() + '/' + FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())) + uf.getFileName());
                json.put("original", uf.getOriginal());
                json.put("dir", FileUtil.mendPath(FileUtil.getDecrease(setupPath, uf.getDir())));
                json.put(Environment.message, language.getLang(LanguageRes.folderWriteError));
            }
        }
        uploadFileDAO.evict(uploadFileDAO.getClassType());
        json.put("list", fileJson);
        setResult(json);
        return ROC;
    }

    public long getSize() {
        if (uploadFile == null) return 0;
        IUploadFile upFile = (IUploadFile) uploadFile;
        return upFile.getFileSize();
    }

    public String getUrl() {
        if (uploadFile == null) return StringUtil.empty;
        IUploadFile upFile = (IUploadFile) uploadFile;
        return upFile.getFileName();
    }

    public String getFileName() {
        if (uploadFile == null) return StringUtil.empty;
        IUploadFile upFile = (IUploadFile) uploadFile;
        return upFile.getFileName();
    }

    public String getState() {
        return json.getString(Environment.message);
    }

    public String getTitle() {
        if (uploadFile == null) return StringUtil.empty;
        IUploadFile upFile = (IUploadFile) uploadFile;
        return upFile.getTitle();
    }

    public String getType() {
        if (uploadFile == null) return StringUtil.empty;
        IUploadFile upFile = (IUploadFile) uploadFile;
        return upFile.getFileType();
    }

    public String getOriginalName() {
        if (uploadFile == null) return StringUtil.empty;
        IUploadFile upFile = (IUploadFile) uploadFile;
        return upFile.getTitle();
    }
}